Jerry's Log

floating point

contents

컴퓨터가 엄청난 범위를 포괄하는 실수(분수를 포함하는 숫자)를 표현하는 시스템을 부동 소수점(Floating-point) 이라고 합니다. 이는 (원자 간 거리처럼 극도로 작은 수부터 천문학적 거리처럼 극도로 큰 수까지) 넓은 범위를 다룰 수 있게 해줍니다.

컴퓨터 메모리는 유한하기 때문에(32비트 또는 64비트와 같은 고정된 비트 블록을 다룸) 수직선상의 모든 숫자를 완벽하게 표현할 수는 없습니다. 대신, IEEE 754라는 표준화된 근사치 시스템을 사용합니다.

여기서 작동 방식에 대해 자세히 알아보겠습니다.


1. 핵심 개념: 이진 과학적 표기법

IEEE 754를 이해하려면 먼저 과학적 표기법을 이해해야 합니다.

IEEE 754는 단순히 이러한 "이진 과학적 표기법"을 32비트 또는 64비트 상자에 담기 위한 표준 규칙입니다.


2. 부동 소수점의 해부학 (32비트 단정밀도)

가장 일반적인 표준인 32비트 부동 소수점(단정밀도)에 초점을 맞추겠습니다. 32비트 메모리 덩어리는 세 가지 별개의 섹션으로 나뉩니다.

  1. 부호 비트 (Sign Bit, 1비트): 숫자가 양수인지 음수인지 결정합니다.
    • 0 = 양수 (+)
    • 1 = 음수 (-)
  2. 지수부 (Exponent, 8비트): 숫자의 "크기" 또는 범위(2의 거듭제곱)를 결정합니다.
  3. 가수부 / 유효숫자 (Mantissa / Significand, 23비트): 숫자의 "정밀도"(실제 자릿수)를 결정합니다.

3. 심층 분석: 변환 원리

이제 32비트 float의 세부 인코딩 방식을 자세히 살펴보겠습니다.

1. 부호 비트 인코딩

음수 -13.625를 가정하면 부호는 음수입니다.

2. 지수부 인코딩 (바이어스 트릭)

정규화된 형태는 $1.101101_2 \times 2^3$이므로 실제 지수는 3입니다. 지수 필드는 음수 지수(예: $2^{-5}$)도 처리해야 합니다.

IEEE 754는 두 번째 부호 비트를 사용하는 대신 바이어스(Bias) 를 사용합니다.

3. 가수부 인코딩 (묵시적 선행 1 트릭)

정규화된 숫자는 1.101101입니다.

이진수 과학적 표기법에서 첫 번째 자릿수는 항상 1입니다(0이라면 소수점을 계속 이동시킬 것이기 때문).

따라서, 이 1은 저장할 필요가 없습니다. 저장 공간을 절약하고 추가 정밀도를 얻기 위해 이 1을 버립니다. 이를 묵시적 선행 1(Implicit Leading One) 또는 "숨겨진 비트"라고 부릅니다.

최종 결과 (조립)

세 부분을 합치면 다음과 같습니다.

1 10000010 10110100000000000000000 (부호) (지수) (가수)


4. 특수 값 (경계 조건)

IEEE 754는 정상적인 숫자가 아닌 개념을 표현하기 위해 특정 지수 패턴을 예약합니다.

값 유형 지수부 가수부 의미
0 모두 0 모두 0 0을 나타냅니다. -0+0이 존재할 수 있다는 점에 유의하세요.
무한대 (Infinity) 모두 1 모두 0 $\pm \infty$를 나타냅니다 (예: 1.0 / 0.0의 결과).
NaN (Not a Number) 모두 1 0이 아님 "숫자가 아님"을 나타냅니다 (예: sqrt(-1) 또는 0.0 / 0.0의 결과).
비정규수 (Subnormal) 모두 0 0이 아님 "묵시적 선행 1" 기능을 끄고 0에 가까운 극도로 작은 숫자를 표현할 수 있게 합니다.

5. 배정밀도 (64비트 Double)

이는 더 높은 정확도를 위해 더 많은 비트를 사용하는 것을 제외하고는 정확히 동일한 논리입니다.

정밀도 비교:


6. 가장 큰 약점: 정밀도 오류

0.1 + 0.2 == 0.30000000000000004일까요?

10진법에서는 $1/3 = 0.3333...$처럼 일부 숫자가 무한히 반복됩니다. 종이에 $1/3$을 완벽하게 쓸 수 없습니다. 2진법에서는 0.1이 무한히 반복됩니다. $0.1$(10진수) = $0.00011001100110011...$(2진수)

가수부에는 23개(또는 52개)의 비트만 있기 때문에, 컴퓨터는 반복되는 시퀀스를 특정 지점에서 잘라내야 합니다. 컴퓨터는 정확한 값이 아닌 0.1의 근사치 를 저장하게 됩니다. 이러한 근사치로 수학 연산을 수행하면 작은 오류들이 누적되어 눈에 띄게 되는 것입니다.

경험 법칙: 돈이나 금융 계산에는 Floats/Doubles를 절대 사용하지 마세요. 대신 Decimal 또는 BigDecimal 타입을 사용해야 합니다.

references